﻿#ifndef COMMANDPARSER_H
#define COMMANDPARSER_H
#include <QList>
#include <QtGlobal>

class QCoreApplication;
class QCommandLineParser;
class IPFiveTuple;
class QHostAddress;
class StartArgs;
class QCommandLineOption;
/**
 * @brief The CommandParser class
 * 解析命令参数。
 */
class CommandParser
{
public:
    CommandParser();
    ~CommandParser();
    /**
     * @brief process 处理命令餐参数。
     * @param app
     */
    void process(QCoreApplication &app);

    /**
     * @brief bServer 是否服务端。
     * @return
     */
    bool bServer();
    /**
     * @brief bFake 是否虚拟模式。
     * @return
     */
    bool bFake();
    /**
     * @brief cmdIPTuple 获取命令的IP五元组。
     * @param dest 输出参数。
     * @return 成功返回true。
     */
    bool cmdIPTuple(IPFiveTuple &dest);
    /**
     * @brief dataIPTuple 获取数据的IP五元组。
     * @param dest 输出参数。
     * @return 成功返回true。
     */
    bool dataIPTuple(IPFiveTuple &dest);

    /**
     * @brief startArgs 获取启动参数。
     * @param dest 输出启动参数。
     * @return 成功获取返回true。
     */
    bool startArgs(StartArgs &dest);
    /**
     * @brief showHelp 显示帮助。
     */
    Q_NORETURN void showHelp();
private:
    /**
     * @brief cmdPort 命令端口
     * @param port
     * @return
     */
    bool cmdPort(quint16 &port);
    /**
     * @brief cmdAddress 命令地址。
     * @param host
     * @return
     */
    bool cmdAddress(QHostAddress &host);
    /**
     * @brief dataPort 命令端口
     * @param port
     * @return
     */
    bool dataPort(quint16 &port);
    /**
     * @brief dataAddress 命令地址。
     * @param host
     * @return
     */
    bool dataAddress(QHostAddress &host);
    /**
     * @brief fetchInt 获取整型数据。
     * @param name
     * @param dest
     * @return
     */
    bool fetchInt(const QCommandLineOption& name, int &dest);
    /**
     * @brief fetchPort 获取指定port
     * @param name 选项的名称。
     * @param port 输出端口。
     * @return
     */
    bool fetchPort(const QCommandLineOption& name, quint16 &port);

    /**
     * @brief fetchAddress 获取地址。
     * @param name 选项名。
     * @param host 输出地址。
     * @return
     */
    bool fetchAddress(const QCommandLineOption& name, QHostAddress &host);

    /**
     * @brief initCmdOption 初始命令行选项。
     */
    void initCmdOption();
private:
    // 定义选项类型。
    enum OptionType
    {
        Opt_CmdPort = 0, // 命令端口。
        Opt_CmdAddress, // 命令地址。
        Opt_DataPort,  // 数据端口。
        Opt_Server, // 服务。
        Opt_UdpMode, // Udp模式。
        Opt_Timeout, // 超时时间。
        Opt_Frequency, // 发包频率
        Opt_Total, // 发包总数。
        Opt_PacketSize, // 数据包每包大小。
        Opt_Warm, // 热身包。
        Opt_Fake, // 测试。
        Opt_TypeCount // 选项类型总数。
    };
private:
    QCommandLineParser *m_parser; // 解析类。
    QList<QCommandLineOption> m_options; // 选项
};

#endif // COMMANDPARSER_H
